package com.llk.myIoLearn.reactorBase.myreactor.httpv2plus;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Processor {
    private static final ExecutorService workerThreads = Executors.newFixedThreadPool(16);
    public void process(SelectionKey key) {
        workerThreads.submit(() -> {
            try {
                SocketChannel channel = (SocketChannel) key.channel();
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                int bytesRead = channel.read(buffer);
                System.out.println("读取bytes"+bytesRead);
//                if (bytesRead == -1) {
//                    channel.close();
//                    key.cancel();
//                    return;
//                }
                key.cancel();

                //切换为读模式
                buffer.flip();
                String msg = new String(buffer.array(), 0, bytesRead);
                System.out.println("Received: " + msg);

                // 生成响应数据并注册写事件
                //将字符串转换为字节数组，并将其包装成一个 ByteBuffer 对象
                // 生成响应体内容
                String responseBody = msg ;
                byte[] bodyBytes = responseBody.getBytes(StandardCharsets.UTF_8);  // 明确指定编码

                // 构建完整的 HTTP 响应报文
                String httpResponse =
                        "HTTP/1.1 200 OK\r\n" +  // 状态行
                                "Content-Type: text/plain; charset=UTF-8\r\n" +  // 响应头：内容类型
                                "Content-Length: " + bodyBytes.length + "\r\n" +  // 响应头：内容长度
                                "\r\n" +  // 空行
                                responseBody;  // 响应体

                // 将报文封装为 ByteBuffer
                ByteBuffer responseBuffer = ByteBuffer.wrap(httpResponse.getBytes(StandardCharsets.UTF_8));
                SelectionKey keyWrite=channel.register(key.selector(), SelectionKey.OP_WRITE);
                keyWrite.attach(responseBuffer);
                System.out.println("Registration write event");
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
    // 处理写操作（直接由 Reactor 线程执行）
    public static void write(ByteBuffer responseBuffer,SelectionKey key) {
        workerThreads.submit(() -> {
            SocketChannel channel = (SocketChannel) key.channel();
            try {
                ByteBuffer buffer = responseBuffer;
                //buffer.hasRemaining()用于判断缓冲区（ByteBuffer）中是否还有剩余可操作数据
                while (buffer.hasRemaining()) {
                    int written = channel.write(buffer);
                    if (written == 0) break;  // 缓冲区已满
                }
                // 写完后恢复读监听写
                //channel.register(key.selector(), SelectionKey.OP_WRITE);
            } catch (ClosedChannelException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            finally {
                // 关闭通道
                key.cancel();
                try {
                    channel.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });

    }
}
